package org.jeecg.common.util.mputil;

import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.service.IService;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.Collection;
import java.util.function.BiConsumer;
import java.util.function.Function;

/**
 * 2表级联操作
 * p是主表c是子表
 *
 * @author zjarlin
 * @since 2023/2/26 09:18
 */
@Data
@NoArgsConstructor
@Transactional(rollbackFor = Exception.class)
public class MpUtil2<P, C> {
    protected IService<P> ps;
    protected IService<C> cs;

    private MpUtil2(IService<P> ps, IService<C> cs) {
        this.ps = ps;
        this.cs = cs;
    }

    public static <P, C> MpUtil2<P, C> of(IService<P> ps, IService<C> cs) {
        return new MpUtil2<P, C>(ps, cs);
    }

    public void pSave(P po, Collection<C> collection, BiConsumer<C,P>consumer) {
        ps.save(po);
        cSave(po, collection, consumer);
    }
    public void pSave(P po, Collection<C> collection, Function<P,String>pgetIdFun,BiConsumer<C,String>csetPidCon) {
        BiConsumer<C,P>consumer=(c,p)-> csetPidCon.accept(c,pgetIdFun.apply(po));
        ps.save(po);
        cSave(po, collection, consumer);
    }

    private void cSave(P po, Collection<C> collection, BiConsumer<C, P> consumer) {
        collection.forEach(c-> {
            consumer.accept(c, po);
        });
        cs.saveBatch(collection);
    }
    public void pRemove(Serializable id, SFunction<C,String> cgetPidFun) {
        cRemove(id, cgetPidFun);
        ps.removeById(id);
    }

    private boolean cRemove(Serializable id, SFunction<C, String> cgetPidFun) {
        return cs.lambdaUpdate().eq(cgetPidFun, id).remove();
    }

    public void pRemoveBatch(Collection<Serializable > ids, SFunction<P,String>pgetIdFun,SFunction<C,String> cgetPidFun) {
        cs.lambdaUpdate().in(cgetPidFun, ids).remove();
        ps.lambdaUpdate().in(pgetIdFun, ids).remove();
    }

    public void pUpdate(P po, Collection<C> collection, SFunction<P,String>pgetIdFun, SFunction<C,String> cgetPidFun, BiConsumer<C, P> consumer) {
        ps.updateById(po);
        String pid = pgetIdFun.apply(po);
        cRemove(pid, cgetPidFun);
        cSave(po, collection, consumer);
    }


}
